package gmodel

import (
	"gorm.io/gorm"
)

// 支持同一模型多redis-name保存
type IDbRedisSet interface {
	IDb
	IRedisSet
	RedisFromDbCondSet(whereParams []interface{}, orderBy string)
	RedisFromDbCondGet() ([]interface{}, string)

	DbRedisGet(child IDbRedisSet, force2Redis ...bool) error
	DbRedisSave(child IDbRedisSet, isAdd ...bool) error
	DbRedisDel(child IDbRedisSet) error
}

type BaseDbRedisSet struct {
	BaseDb
	BaseRedisSet

	whereParams []interface{}
	orderBy     string
}

func (this *BaseDbRedisSet) RedisFromDbCondSet(whereParams []interface{}, orderBy string) {
	this.whereParams = whereParams
	this.orderBy = orderBy
}
func (this *BaseDbRedisSet) RedisFromDbCondGet() ([]interface{}, string) {
	return this.whereParams, this.orderBy
}

func (this *BaseDbRedisSet) Init(m *BaseRedisSetModel) {
	this.SetRedisName(m.Name)
	this.SetRedisValue(m.Value)
	this.SetRedisExpire(m.Expire)
	this.RedisFromDbCondSet(m.DbWhere, m.DbOrder)
}

func (this *BaseDbRedisSet) SetRMT(child IDbRedisSet, typ int8) IDbRedisSet {
	child.SetRedisType(typ)
	return child
}

// 依赖:this.id,默认同步到redis
func (this *BaseDbRedisSet) DbRedisGet(child IDbRedisSet, syncRedis ...bool) error {
	var (
		err     error
		cond    []interface{}
		orderBy string
	)
	//this.SetRedisModel()
	if err = this.RedisGet(child); err != nil {
		cond, orderBy = child.RedisFromDbCondGet()
		if err = this.DbFirst(child, orderBy, cond...); err != nil {
			return err
		} else if len(syncRedis) == 0 || syncRedis[0] {
			_ = this.RedisSet(child)
		}
		return nil
	}
	return nil
}

func (this *BaseDbRedisSet) DbRedisSave(child IDbRedisSet, isAdd ...bool) (err error) {
	return child.Db().Transaction(func(tx *gorm.DB) error {
		if child.GetId() == 0 || (len(isAdd) > 0 && isAdd[0]) {
			if err = tx.Create(child).Error; err != nil { //新增到数据库
				return err
			}
		} else {
			if err = tx.Save(child).Error; err != nil {
				return err
			}
			//更新操作不更新0值【0,"",null】字段，所以这个这适合
			//if err = tx.Model(child).Updates(child).Error; err != nil { //更新数据库
			//	return err
			//}
		}
		if err = this.RedisSet(child); err != nil {
			return err
		}
		//返回 nil 提交事务
		return nil
	})
}

func (this *BaseDbRedisSet) DbRedisDel(child IDbRedisSet) error {
	return child.Db().Transaction(func(tx *gorm.DB) error {
		if err := this.RedisDel(child); err != nil {
			return err
		} else if err = tx.Delete(child).Error; err != nil {
			return err
		}
		return nil
	})
}
